#include <chrono>
#include <functional>
#include <memory>
#include <string>

#include <filesystem>
#include <csignal>
#include <cstdlib>
#include <fstream>
#include <iomanip>  // For std::put_time

#include "rclcpp/rclcpp.hpp"
#include "common_lib/glog/glog.h"

std::string g_camera_name = "common_test";  // Assuming this is declared elsewhere
void signalHandler(const char *data, int size) {
  std::string log_dir = "/home/xxty/user_data/gdb/";

  // get current time
  std::time_t now = std::time(nullptr);
  std::tm *local_time = std::localtime(&now);

  // format date and time to string, format as "2024_05_20_12_34_56"
  std::ostringstream time_stream;
  time_stream << std::put_time(local_time, "%Y_%m_%d_%H_%M_%S");

  // generate log file name
  std::string log_file_name = g_camera_name + "_crash_stack_trace_" + time_stream.str() + ".log";
  std::string log_file_path = log_dir + log_file_name;

  if (!std::filesystem::exists(log_dir)) {
    std::filesystem::create_directories(log_dir);
  }

  std::cout << "Log crash stack trace to " << log_file_path << std::endl;
  // std::ofstream log_file(log_file_path, std::ios::app);

  std::ofstream fs(log_file_path, std::ios::app);
  std::string str = std::string(data, size);
  fs << str;
  fs.close();
  LOG(INFO) << str;
}


class TestBackward : public rclcpp::Node{
    public:
        TestBackward();
        ~TestBackward() = default;

        void test();
};  

TestBackward::TestBackward(): Node("test_backward_node"){
  LOG(INFO) << "this is info.";
  LOG(WARNING) << "this is warning.";
  LOG(ERROR) <<"this is error.";
  test();
}

void TestBackward::test(){
    std::cout << "test" << std::endl;
    int* p = nullptr;
    *p = 42; // 这会触发SIGSEGV
}

int main(int argc, char * argv[]){
    // signal(SIGSEGV, signalHandler);  // segment fault
    // signal(SIGABRT, signalHandler);  // abort
    // signal(SIGFPE, signalHandler);   // float point exception
    // signal(SIGILL, signalHandler);   // illegal instruction

    // struct sigaction act {};
    // act.sa_flags = SA_NODEFER | SA_RESETHAND;
    // act.sa_handler = &signalHandler;
    // sigfillset(&act.sa_mask);
    // sigdelset(&act.sa_mask, SIGSEGV);
    // if (sigaction(SIGSEGV, &act, nullptr) == -1)
    //     std::exit(EXIT_FAILURE);

    FLAGS_colorlogtostderr = true;   // log信息区分颜色
    FLAGS_logtostderr = 1;           // 允许log信息打印到屏幕
    google::SetStderrLogging(google::GLOG_INFO);  // 输出log的最低等级是 INFO (可以设置为WARNING或者更高)
    google::InstallFailureSignalHandler();     // 配置安装程序崩溃失败信号处理器
    google::InstallFailureWriter(&signalHandler);  // 安装配置程序失败信号的信息打印过程，设置回调函数
    google::InitGoogleLogging((const char *)argv[0]);  // 用当前可执行程序初始化glog

  

    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<TestBackward>());
    rclcpp::shutdown();
    return 0;
}